<?php
  
require_once(dirname(__FILE__).'/resourcepage_extension.php');

/**
 * Base class for 'pull' extensions. 
 * 
 * Pull extensions provide blocks of content that can be added to resource pages. 
 * These appear as entire chunks and are not editable. (I.e. users can create or 
 * delete the block, but can't edit the items in it.) The content may be 
 * automatically updated periodically.
 * 
 * To implement a pull extension you need to create a folder myextension inside 
 * resourcepage/extensions, and create a file there called myextension.php that
 * includes a class resourcepage_myextension which extends this base class.
 * 
 * In order to make a 'default' extension (i.e. if you aren't going to override
 * anything in this class except the basics) you need to:
 * 1. In resourcepage_myextension, override get_database_version to return an 
 *    initial version number. 
 * 2. Create tables.xml (in your extension folder) that defines your tables;
 *    include a &lt;maintable>.
 * 3. Create edit.xml (in your extension folder) that defines your settings page.
 * 4. Create moodle/lang/en/resourcepage_myextension.php, which must include the
 *    following:
 *    - name (Display name for this extension, beginning with capital letter)
 *    - Other strings as needed for edit.xml
 *
 * @copyright &copy; 2006 The Open University
 * @author s.marshall@open.ac.uk
 * @license http://www.gnu.org/copyleft/gpl.html GNU Public License
 * @package resourcepage
 */
abstract class resourcepage_extension_pull extends resourcepage_extension {
    
    /**
     * Constructs extension object.
     * @param object $resourcepage Resourcepage module object
     */ 
    function __construct(&$resourcepage) {
        parent::__construct($resourcepage);
    }
    
    /**
     * Gets title to use for add button etc. 
     * 
     * Default is taken from 'name' key in the localisation file.
     */
    public function get_display_name() {
        return get_string('name','resourcepage_'.$this->get_name());
    }
    
    /**
     * Determines whether the add button should appear when editing
     * resources pages. This method is only called when editing anyway,
     * you don't need to check edit permissions.
     * 
     * Default is true.
     * @param object $resourcepage Data from the resourcepage table row
     * @param object $course Data from the course table 
     * @return bool True if button is enabled, false otherwise.
     */    
    public function is_add_allowed($resourcepage,$course) {
        return true;
    }
    
    /**
     * Displays the HTML content of the form used to edit instances
     * of this extension.
     * @param int $containerid ID of container that we are editing settings
     *   for, or 0 if this is a new one being added.
     * @param object $course Course object
     * @param object $cm Course-module object
     * @param array $parameters Optional name=>value array of extra hidden values for form
     */    
    public function show_edit_form($containerid,$course,$cm,$parameters=array()) {
        global $CFG;
        if (file_exists($CFG->dirroot.'/mod/resourcepage/extensions/'.$this->get_name().'/edit_form.php')) {
            require_once($CFG->dirroot.'/mod/resourcepage/extensions/'.$this->get_name().'/edit_form.php');
            $extclass = 'ext_'.$this->get_name().'_edit_form';
            $editform = new $extclass('saveextension.php');

            // Get extension fields
            $fields_ext = array();
            if($containerid != 0) {
                // Get row from extension's table as array
                $fields_ext = (array)$this->get_maintable_record($containerid);
            }

            // Append input parameters + default fields
            $fields_form = array_merge($fields_ext, $parameters);
            $fields_form['containerid'] = $containerid;                
            $fields_form['extension'] = $this->get_name();
            $fields_form['coursemodule'] = $cm->id;

            // Set form default values
            $editform->set_data($fields_form);

            // display form
            $editform->display();
        } else {
            error('No formslib form description file found for this activity.');
        }
    }
    
    /**
     * @param int $containerid ID of container
     * @param bool $allowfalse If true, will return false if it doesn't exist rather than 
     *   throwing exception
     * @return mixed Returns the record from the extension's main table corresponding to 
     *   given container, or false if it doesn't exist and $allowfalse was set.
     * @throws Exception if it doesn't exist and allowfalse wasn't set, or there's an 
     *   SQL error.
     */
    protected function get_maintable_record($containerid,$allowfalse=false) {
        $rs=$this->do_sql(
            'SELECT * FROM '.$this->get_maintable_name().' WHERE containerid='.$containerid);
        if($rs->EOF) {
            if($allowfalse) {
                return false;
            }
            throw new Exception("Couldn't find extension record $containerid in ".
                $this->get_maintable_name()); 
        }
        
        
        $objectversion=new stdClass;
        foreach($rs->fields as $key=>$value) {
            if(preg_match('/[^0-9]/',$key)) {
                $objectversion->{strtolower($key)}=$value;
            }
        }
        return $objectversion;
    }
    
    /**
     * Can be overridden to set form values prior to displaying the settings
     * page. Default reads a row from the main table.
     * @param int $container ID of container that we are editing settings
     *   for, or 0 if this is a new one being added.
     * @param object $course Course object
     * @param object &$form Form data object
     * @return maintable record id 
     */
    protected function init_edit_form($container,$course,&$form) {

        // Define maintable record id
        $id = 0;

        if($container!=0) {
            // Get row from extension's table as array
            $record=(array)$this->get_maintable_record($container);
                
            // Add each one to the form
            foreach($record as $name=>$value) {
                $form->{$name}=$value;
            }

            // Set maintable record id
            $id = $record['id'];
        }
        
        // Note: This method could've just assigned the get_record
        // results to the $form, but I did it this way in case 
        // at some later point $form might have predefined values
        // that we don't want to throw away.

        // Return maintable record id
        return $id;
    }
    
    /**
     * Called to create an instance of this extension. 
     * 
     * By default, just adds a record to the module's main table. 
     * @param object $content Object containing form fields from the setup page.
     */    
    public function add_instance($content) {        
        $this->before_addupdate_instance($content,true);
        $this->insert_maintable_record($content);
    }
        
    protected function insert_maintable_record($record) {
        global $db;
        // No addslashes_object as appears to be escaped for rssfeed
        if (!insert_record('resourcepage_x_'.$this->get_name(), $record, false)) {
            throw new Exception('resourcepage_x_'.$this->get_name().' SQL error: '.$db->ErrorMsg());
        }
    }
    
    /**
     * Called to update settings for an instance of this extension. 
     * 
     * By default, just updates the database record. 
     * @param object $content Object containing form fields from the setup page
     */    
    public function update_instance($content) {
        $this->before_addupdate_instance($content,false);
               
        global $db;
        // No addslashes_object as appears to be escaped for rssfeed
        if (!update_record('resourcepage_x_'.$this->get_name(), $content)) {
            throw new Exception('resourcepage_x_'.$this->get_name().' SQL error: '.$db->ErrorMsg());
        }
    }
    
    /**
     * Overridable method that gets called before either adding or updating an
     * instance record. You can use this if the form fields from the setup page
     * might not match the fields that need to be added to the database.
     * @param &$content Object containing form fields from the setup page.
     * @param $isadd True if this is add, false if it's update
     */
    protected function before_addupdate_instance(&$content,$isadd) {
    }    
    
    public function before_deleting_container($containerid) {
        if(!$record=$this->get_maintable_record($containerid,true)) {
            // Not owned by this extension 
            return; 
        }
        
        // Give subclass a chance to do something else
        $this->before_deleting_instance($record);
        
        $this->do_sql('DELETE FROM '.$this->get_maintable_name().' WHERE containerid='.$containerid);
            
        // Give subclass a chance to do something else
        $this->after_deleting_instance($record);
    }        
    
    /**
     * Called by before_deleting_container just before an instance is deleted.
     * 
     * Default does nothing. Override to achieve specific behaviour
     * while retaining the standard delete that's done for you. 
     * @param object $record Object of database fields 
     */    
    protected function before_deleting_instance($record) {
    }
    /**
     * Called by before_deleting_container just after an instance is deleted.
     * 
     * Default does nothing. Override to achieve specific behaviour
     * while retaining the standard delete that's done for you. 
     * @param object $record Object of database fields 
     */    
    protected function after_deleting_instance($record) {
    }
    
    /**
     * Called to update the extension's items in a particular
     * container. The extension should, if necessary, clear and
     * recreate its items.
     * 
     * Default does nothing.
     * @param int $containerid Identifies the extension instance
     * @param int &$nextupdate Should set this to the time at which 
     *   another update is requested. Default is for daily updates.
     * @param string &$plugininfo Optionally set this to specify information
     *   that will appear in the editing view of the resourcepage
     * @throws Exception if anything goes wrong.
     */
    public function update($containerid,&$nextupdate,&$plugininfo) {
    }
    
    /**
     * Write backup XML for one container of this extension. Default
     * version just saves all the fields from the main table. 
     * @param xml_backup &$backup Backup handler
     * @param module_resourcepage &$rp Resourcepage object
     * @param int $containerid Identifies the extension instance
     */
    public function backup(&$backup,&$rp,$containerid) {
        $backup->tag_start('PULLEXTENSION');
        $record=(array)$this->get_maintable_record($containerid);
        foreach($record as $name=>$value) {
            if($name=='containerid') {
                continue;
            }
            $backup->tag_full_notnull(strtoupper($name),$value);
        }
        $backup->tag_end('PULLEXTENSION');
    }
    
    /**
     * Restores from backup XML for one container of this extension. 
     * Default version restores fields from main table. 
     * @param object $restoresettings Moodle object with restore settings
     * @param module_resourcepage &$rp Resourcepage object
     * @param int $containerid Identifies the newly-created container
     * @param array $xml Dodgy Moodle parsed XML format 
     */
    public function restore($restoresettings,&$rp,$containerid,$xml) {
        // Fill record
        $record=new stdClass;
        $record->containerid=$containerid;
        foreach($xml['PULLEXTENSION'][0]['#'] as $field=>$data) {
            $record->{strtolower($field)}=$data[0]['#'];
        }
        
        // Insert it
        $this->insert_maintable_record($record);        
    }
}

?>
